// 请求拦截器
const tokenManager = require('./tokenManager');

// 原始wx.request函数引用
const originalRequest = wx.request;
const originalUploadFile = wx.uploadFile;

// 是否正在刷新token
let isRefreshing = false;
// 等待刷新token的请求队列
let refreshQueue = [];

/**
 * 处理请求队列
 * @param {string} token - 新的token
 * @param {boolean} success - 刷新是否成功
 */
function processQueue(token, success) {
  refreshQueue.forEach(({ resolve, reject }) => {
    if (success) {
      resolve(token);
    } else {
      reject(new Error('Token刷新失败'));
    }
  });
  
  // 清空队列
  refreshQueue = [];
}

/**
 * 刷新token并处理请求队列
 * @returns {Promise<string>} - 新的token
 */
function refreshTokenAndProcess() {
  // 如果已经在刷新，则加入等待队列
  if (isRefreshing) {
    return new Promise((resolve, reject) => {
      refreshQueue.push({ resolve, reject });
    });
  }
  
  // 开始刷新token
  isRefreshing = true;
  
  return tokenManager.refreshToken()
    .then(data => {
      isRefreshing = false;
      processQueue(data.token, true);
      return data.token;
    })
    .catch(error => {
      isRefreshing = false;
      processQueue(null, false);
      
      // 刷新失败，跳转到登录页面
      wx.navigateTo({
        url: '/pages/login/login'
      });
      
      return Promise.reject(error);
    });
}

/**
 * 处理请求失败
 * @param {Object} error - 错误信息
 * @param {Function} reject - Promise的reject函数
 */
function handleRequestError(error, reject) {
  // 自定义错误处理逻辑
  const customError = {
    code: error.statusCode || 500,
    message: '请求失败',
    data: error.data || null,
    originalError: error
  };
  
  // 根据状态码处理特定错误
  switch (customError.code) {
    case 401:
      customError.message = '未授权或授权已过期';
      break;
    case 403:
      customError.message = '无权访问该资源';
      break;
    case 404:
      customError.message = '请求的资源不存在';
      break;
    case 500:
      customError.message = '服务器内部错误';
      break;
    case 429:
      customError.message = '请求过于频繁，请稍后再试';
      break;
  }
  
  // 特殊错误的UI处理
  if ([403, 404, 500].includes(customError.code)) {
    wx.showToast({
      title: customError.message,
      icon: 'none',
      duration: 2000
    });
  }
  
  reject(customError);
}

/**
 * 拦截处理请求
 * @param {Object} options - 原始请求参数
 * @param {Function} originalMethod - 原始请求方法
 * @returns {Promise} - 处理后的Promise
 */
function interceptRequest(options, originalMethod) {
  return new Promise((resolve, reject) => {
    // 克隆原始参数
    const clonedOptions = { ...options };
    
    // 保存原始成功和失败回调
    const originalSuccess = clonedOptions.success;
    const originalFail = clonedOptions.fail;
    
    // 获取当前token
    const token = tokenManager.getAccessToken();
    
    // 添加认证头（如果存在header则合并，否则创建）
    if (token) {
      clonedOptions.header = {
        ...(clonedOptions.header || {}),
        'Authorization': `Bearer ${token}`
      };
    }
    
    // 处理成功回调
    clonedOptions.success = async function(res) {
      // 如果是token过期
      if (res.statusCode === 401 || (res.data && res.data.code === 401)) {
        try {
          // 尝试刷新token
          const newToken = await refreshTokenAndProcess();
          
          // 更新请求头中的token
          clonedOptions.header = {
            ...(clonedOptions.header || {}),
            'Authorization': `Bearer ${newToken}`
          };
          
          // 重新发起原始请求
          delete clonedOptions.success;
          delete clonedOptions.fail;
          
          // 再次调用，使用原始方法
          originalMethod({
            ...clonedOptions,
            success: function(newRes) {
              if (typeof originalSuccess === 'function') {
                originalSuccess(newRes);
              }
              resolve(newRes);
            },
            fail: function(newError) {
              if (typeof originalFail === 'function') {
                originalFail(newError);
              }
              handleRequestError(newError, reject);
            }
          });
        } catch (error) {
          handleRequestError(error, reject);
        }
        return;
      }
      
      // 非401错误，直接处理
      if (typeof originalSuccess === 'function') {
        originalSuccess(res);
      }
      resolve(res);
    };
    
    // 处理失败回调
    clonedOptions.fail = function(error) {
      if (typeof originalFail === 'function') {
        originalFail(error);
      }
      handleRequestError(error, reject);
    };
    
    // 执行原始请求
    originalMethod(clonedOptions);
  });
}

/**
 * 覆盖原始的wx.request函数
 */
function setupRequestInterceptor() {
  // 覆盖wx.request
  wx.request = function(options) {
    return interceptRequest(options, originalRequest);
  };
  
  // 覆盖wx.uploadFile
  wx.uploadFile = function(options) {
    return interceptRequest(options, originalUploadFile);
  };
}

module.exports = {
  setup: setupRequestInterceptor
}; 